package com.myself.common.config;

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer
import com.myself.common.model.ResultData
import com.myself.common.model.ReturnCode
import org.ktorm.jackson.KtormModule
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.MethodParameter
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
import org.springframework.http.server.ServerHttpRequest
import org.springframework.http.server.ServerHttpResponse
import org.springframework.lang.Nullable
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestControllerAdvice
import org.springframework.web.client.RestTemplate
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice
import java.time.format.DateTimeFormatter

@Configuration
open class JacksonConfig : WebMvcConfigurer {
    @Bean
    open fun jacksonCustomizer(): Jackson2ObjectMapperBuilderCustomizer {
        return Jackson2ObjectMapperBuilderCustomizer { builder: Jackson2ObjectMapperBuilder ->
            builder.modulesToInstall(KtormModule())
            builder.serializerByType(
                java.time.LocalDateTime::class.java,
                LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
            )
        }
    }
}
/**
 * @author jam
 * @date 2021/7/8 10:10 上午
 */
@RestControllerAdvice
class ResponseAdvice : ResponseBodyAdvice<Any?> {
    @Autowired
    private val objectMapper: ObjectMapper? = null


    override fun supports(methodParameter: MethodParameter, aClass: Class<out HttpMessageConverter<*>>): Boolean {
        return true
    }

    override fun beforeBodyWrite(
        @Nullable o: Any?,
        methodParameter: MethodParameter,
        mediaType: MediaType,
        aClass: Class<out HttpMessageConverter<*>>,
        serverHttpRequest: ServerHttpRequest,
        serverHttpResponse: ServerHttpResponse
    ): Any? {
        if (o is String) {
            return objectMapper!!.writeValueAsString(ResultData.success(o))
        }
        if (o is ResultData<*>) {
            return o
        }
        return ResultData.success(o)
    }
}

@RestControllerAdvice
class RestExceptionHandler {
    /**
     * 默认全局异常处理。
     * @param e the e
     * @return ResultData
     */
    @ExceptionHandler(Exception::class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    fun exception(e: Exception): ResultData<String> {
        return ResultData.fail(ReturnCode.RC500.code, e.message!!)
    }
}


